import { mat4 } from 'gl-matrix'

// webgl 矩阵变换
let dpr = window.devicePixelRatio

const vertexShaderSource = `
    precision mediump float;
    attribute vec2 aPosition;

    uniform mat4 modelMatrix;

    void main() {
        gl_Position = modelMatrix * vec4(aPosition, 0.0, 1.0);
        gl_PointSize = 5.0;
    }
`;

const fragmentShaderSource = `
    precision mediump float;

    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;

function createShader(gl, type, source) {
    const shader = gl.createShader(type);
    gl.shaderSource(shader, source);
    gl.compileShader(shader);
    
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.error('着色器编译失败: ' + gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
    }
    return shader;
}

function createProgram(gl, vertexShader, fragmentShader) {
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        console.error('程序链接失败: ' + gl.getProgramInfoLog(program));
        gl.deleteProgram(program);
        return null;
    }
    return program;
}

function main() {
    let canvas = document.createElement('canvas')
    canvas.width = window.innerWidth * dpr
    canvas.height = window.innerHeight * dpr
    document.getElementById('app').appendChild(canvas)

    const gl = canvas.getContext('webgl');
    if (!gl) {
        console.error('WebGL不可用');
        return;
    }
    // 创建着色器程序
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
    const program = createProgram(gl, vertexShader, fragmentShader);
    if (!program) {
        return;
    }
    gl.useProgram(program);

    // 创建缓冲区
    const positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        -0.5, -0.5,
        0.5, -0.5,
        0.5, 0.5,
        -0.5, 0.5,
        0.0, 0.0,
    ]), gl.STATIC_DRAW);

    // 启用顶点属性
    const positionAttribute = gl.getAttribLocation(program, 'aPosition');
    gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionAttribute);

    const modelMatrixLocal = gl.getUniformLocation(program, "modelMatrix");
    const viewportSize = Math.min(canvas.width, canvas.height);
    gl.viewport(0, 0, viewportSize, viewportSize);

    // 创建各个矩阵
    let modelMatrix = mat4.create();  // 模型矩阵
    let viewMatrix = mat4.create();   // 视图矩阵
    let projMatrix = mat4.create();   // 投影矩阵
    let mvpMatrix = mat4.create();    // 最终的组合矩阵

    let radians = 0.0;
    // 在 render 函数中修改矩阵计算部分
    function render() {
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        mat4.identity(modelMatrix);
        mat4.scale(modelMatrix, modelMatrix, [0.5, 1, 1]);
        mat4.translate(modelMatrix, modelMatrix, [2, 0, 0]);

        let m = mat4.create()
        mat4.rotate(m, m, radians, [1, 1, 1]);
        mat4.mul(modelMatrix, modelMatrix, m);

        // 设置视图矩阵
        mat4.lookAt(viewMatrix, 
            [0, 0, 10],    // 相机位置
            [0, 0, 0],    // 观察点
            [0, 1, 0]     // 上方向
        );

        // 设置投影矩阵
        mat4.perspective(projMatrix,
            45 * Math.PI / 180,  // 视角（转换为弧度）
            canvas.width / canvas.height,  // 宽高比
            0.1,    // 近平面
            100.0   // 远平面
        );

        // 组合矩阵：投影矩阵 * 视图矩阵 * 模型矩阵
        mat4.multiply(mvpMatrix, projMatrix, viewMatrix);
        mat4.multiply(mvpMatrix, mvpMatrix, modelMatrix);

        // 传递最终矩阵到着色器
        gl.uniformMatrix4fv(modelMatrixLocal, false, mvpMatrix);

        // 绘制
        gl.drawArrays(gl.POINTS, 0, 5);
        gl.drawArrays(gl.LINE_LOOP, 0, 4);

        requestAnimationFrame(render);
        radians+=0.01;
    }
    render()
}

main();